{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: pandas in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (1.5.3)\r\n",
      "Requirement already satisfied: scikit-learn in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (1.2.2)\r\n",
      "Requirement already satisfied: numpy in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (1.24.2)\r\n",
      "Requirement already satisfied: matplotlib in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (3.7.1)\r\n",
      "Collecting seaborn\r\n",
      "  Downloading seaborn-0.12.2-py3-none-any.whl (293 kB)\r\n",
      "\u001B[2K     \u001B[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001B[0m \u001B[32m293.3/293.3 kB\u001B[0m \u001B[31m1.2 MB/s\u001B[0m eta \u001B[36m0:00:00\u001B[0m00:01\u001B[0m00:01\u001B[0m\r\n",
      "\u001B[?25hRequirement already satisfied: python-dateutil>=2.8.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from pandas) (2.8.2)\r\n",
      "Requirement already satisfied: pytz>=2020.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from pandas) (2023.2)\r\n",
      "Requirement already satisfied: scipy>=1.3.2 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from scikit-learn) (1.10.1)\r\n",
      "Requirement already satisfied: joblib>=1.1.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from scikit-learn) (1.2.0)\r\n",
      "Requirement already satisfied: threadpoolctl>=2.0.0 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from scikit-learn) (3.1.0)\r\n",
      "Requirement already satisfied: contourpy>=1.0.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (1.0.7)\r\n",
      "Requirement already satisfied: cycler>=0.10 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (0.11.0)\r\n",
      "Requirement already satisfied: fonttools>=4.22.0 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (4.39.2)\r\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (1.4.4)\r\n",
      "Requirement already satisfied: packaging>=20.0 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (23.0)\r\n",
      "Requirement already satisfied: pillow>=6.2.0 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (9.4.0)\r\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from matplotlib) (3.0.9)\r\n",
      "Requirement already satisfied: six>=1.5 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)\r\n",
      "Installing collected packages: seaborn\r\n",
      "Successfully installed seaborn-0.12.2\r\n",
      "\r\n",
      "\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m A new release of pip available: \u001B[0m\u001B[31;49m22.3.1\u001B[0m\u001B[39;49m -> \u001B[0m\u001B[32;49m23.0.1\u001B[0m\r\n",
      "\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m To update, run: \u001B[0m\u001B[32;49mpip3 install --upgrade pip\u001B[0m\r\n"
     ]
    }
   ],
   "source": [
    "!pip3 install pandas scikit-learn numpy matplotlib seaborn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "# Update the path to your local NSL-KDD dataset file\n",
    "train_data_url = '../NSL-KDD/KDDTrain+.txt'\n",
    "test_data_url = '../NSL-KDD/KDDTest+.txt'\n",
    "\n",
    "# Define column names\n",
    "columns = ['duration', 'protocol_type', 'service', 'flag', 'src_bytes', 'dst_bytes', 'land', 'wrong_fragment', 'urgent',\n",
    "           'hot', 'num_failed_logins', 'logged_in', 'num_compromised', 'root_shell', 'su_attempted', 'num_root', 'num_file_creations', 'num_shells', 'num_access_files', 'num_outbound_cmds', 'is_host_login', 'is_guest_login', 'count',\n",
    "           'srv_count', 'serror_rate', 'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate', 'same_srv_rate',\n",
    "           'diff_srv_rate', 'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate',\n",
    "           'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'dst_host_serror_rate',\n",
    "           'dst_host_srv_serror_rate', 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate', 'attack_type', 'difficulty']\n",
    "\n",
    "# Load the data\n",
    "train_data = pd.read_csv(train_data_url, names=columns)\n",
    "test_data = pd.read_csv(test_data_url, names=columns)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "\n",
    "# Combine the train and test datasets for preprocessing\n",
    "combined_data = pd.concat([train_data, test_data])\n",
    "\n",
    "# Encode the categorical features\n",
    "categorical_features = ['protocol_type', 'service', 'flag', 'attack_type']\n",
    "for feature in categorical_features:\n",
    "    encoder = LabelEncoder()\n",
    "    combined_data[feature] = encoder.fit_transform(combined_data[feature])\n",
    "\n",
    "# Split the combined dataset back into train and test datasets\n",
    "train_data = combined_data.iloc[:len(train_data), :]\n",
    "test_data = combined_data.iloc[len(train_data):, :]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train = train_data.drop(columns=['attack_type', 'difficulty'])\n",
    "y_train = train_data['attack_type']\n",
    "X_test = test_data.drop(columns=['attack_type', 'difficulty'])\n",
    "y_test = test_data['attack_type']"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "from sklearn.ensemble import AdaBoostClassifier\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.metrics import classification_report\n",
    "\n",
    "# Create an Adaptive Boosting classifier\n",
    "ab_clf = AdaBoostClassifier(base_estimator=DecisionTreeClassifier(max_depth=1), n_estimators=100, learning_rate=0.5)\n",
    "\n",
    "# Train the classifier\n",
    "ab_clf.fit(X_train, y_train)\n",
    "\n",
    "# Test the classifier\n",
    "ab_y_pred = ab_clf.predict(X_test)\n",
    "\n",
    "# Evaluate the classifier\n",
    "print(\"Adaptive Boosting Classifier:\")\n",
    "print(classification_report(y_test, ab_y_pred))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "class GreyWolfOptimizer:\n",
    "    def __init__(self, obj_function, search_space, pack_size, n_iter):\n",
    "        self.obj_function = obj_function\n",
    "        self.search_space = search_space\n",
    "        self.pack_size = pack_size\n",
    "        self.n_iter = n_iter\n",
    "        self.dim = len(search_space)\n",
    "\n",
    "    def optimize(self):\n",
    "        # Initialize pack positions\n",
    "        pack_positions = np.array(\n",
    "            [np.random.uniform(space[0], space[1], self.pack_size) for space in self.search_space]).T\n",
    "\n",
    "        # Calculate objective function values for each position\n",
    "        obj_values = np.array([self.obj_function(pos) for pos in pack_positions])\n",
    "\n",
    "        # Find the initial alpha, beta, and delta wolves\n",
    "        alpha_idx, beta_idx, delta_idx = np.argsort(obj_values)[:3]\n",
    "\n",
    "        alpha = pack_positions[alpha_idx]\n",
    "        beta = pack_positions[beta_idx]\n",
    "        delta = pack_positions[delta_idx]\n",
    "\n",
    "        # Start GWO iterations\n",
    "        for iter_idx in range(self.n_iter):\n",
    "            a = 2 - iter_idx * (2 / self.n_iter)  # Linearly decreasing 'a' parameter\n",
    "\n",
    "          for iter_idx in range(self.n_iter):\n",
    "            a = 2 - iter_idx * (2 / self.n_iter)  # Linearly decreasing 'a' parameter\n",
    "\n",
    "            for i in range(self.pack_size):\n",
    "                # Update positions of the pack members\n",
    "                for j in range(self.dim):\n",
    "                    r1, r2 = np.random.rand(2)  # Random coefficients\n",
    "\n",
    "                    # Calculate the updating components for each of the three leading wolves\n",
    "                    A_alpha = 2 * a * r1 - a\n",
    "                    A_beta = 2 * a * r1 - a\n",
    "                    A_delta = 2 * a * r1 - a\n",
    "\n",
    "                    C_alpha = 2 * r2\n",
    "                    C_beta = 2 * r2\n",
    "                    C_delta = 2 * r2\n",
    "\n",
    "                    D_alpha = abs(C_alpha * alpha[j] - pack_positions[i, j])\n",
    "                    D_beta = abs(C_beta * beta[j] - pack_positions[i, j])\n",
    "                    D_delta = abs(C_delta * delta[j] - pack_positions[i, j])\n",
    "\n",
    "                    # Update the position of the current pack member\n",
    "                    pack_positions[i, j] = (alpha[j] - A_alpha * D_alpha + beta[j] - A_beta * D_beta +\n",
    "                                            delta[j] - A_delta * D_delta) / 3\n",
    "\n",
    "                    # Clip the updated position to the search space bounds\n",
    "                    pack_positions[i, j] = np.clip(pack_positions[i, j], self.search_space[j][0],\n",
    "                                                   self.search_space[j][1])\n",
    "                # Calculate the updated objective function value\n",
    "                updated_obj_value = self.obj_function(pack_positions[i])\n",
    "\n",
    "                # Update the alpha, beta, and delta wolves if necessary\n",
    "                if updated_obj_value < obj_values[alpha_idx]:\n",
    "                    delta_idx = beta_idx\n",
    "                    beta_idx = alpha_idx\n",
    "                    alpha_idx = i\n",
    "                elif updated_obj_value < obj_values[beta_idx]:\n",
    "                    delta_idx = beta_idx\n",
    "                    beta_idx = i\n",
    "                elif updated_obj_value < obj_values[delta_idx]:\n",
    "                    delta_idx = i\n",
    "\n",
    "                # Update the objective function value for the current pack member\n",
    "                obj_values[i] = updated_obj_value\n",
    "\n",
    "                # Update the positions of the alpha, beta, and delta wolves\n",
    "                alpha = pack_positions[alpha_idx]\n",
    "                beta = pack_positions[beta_idx]\n",
    "                delta = pack_positions[delta_idx]\n",
    "\n",
    "\n",
    "        # Return the best solution found\n",
    "        return alpha"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.metrics import f1_score\n",
    "\n",
    "# Define objective function for GWO\n",
    "def objective_function(params):\n",
    "    max_depth, min_samples_split = int(params[0]), int(params[1])\n",
    "\n",
    "    classifier = DecisionTreeClassifier(max_depth=max_depth, min_samples_split=min_samples_split)\n",
    "    classifier.fit(X_train, y_train)\n",
    "    y_pred = classifier.predict(X_test)\n",
    "\n",
    "    # Use F1 score as the optimization metric\n",
    "    return -f1_score(y_test, y_pred, average='micro')\n",
    "\n",
    "# Define search space\n",
    "search_space = [\n",
    "    (1, 50),  # max_depth\n",
    "    (2, 100)  # min_samples_split\n",
    "]\n",
    "\n",
    "# Create GWO optimizer\n",
    "gwo_optimizer = GreyWolfOptimizer(obj_function=objective_function, search_space=search_space, pack_size=5, n_iter=50)\n",
    "\n",
    "# Run GWO optimization\n",
    "best_params = gwo_optimizer.optimize()\n",
    "\n",
    "# Create the final classifier with optimized hyperparameters\n",
    "gwo_clf = DecisionTreeClassifier(max_depth=int(best_params[0]), min_samples_split=int(best_params[1]))\n",
    "gwo_clf.fit(X_train, y_train)\n",
    "gwo_y_pred = gwo_clf.predict(X_test)\n",
    "\n",
    "# Evaluate the classifier\n",
    "print(\"Grey Wolf Optimizer Classifier:\")\n",
    "print(classification_report(y_test, gwo_y_pred))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "\n",
    "ab_f1 = f1_score(y_test, ab_y_pred, average='micro')\n",
    "gwo_f1 = f1_score(y_test, gwo_y_pred, average='micro')\n",
    "\n",
    "print(f\"Adaptive Boosting Classifier F1 Score: {ab_f1:.4f}\")\n",
    "print(f\"Grey Wolf Optimizer Classifier F1 Score: {gwo_f1:.4f}\")\n",
    "\n",
    "if ab_f1 > gwo_f1:\n",
    "    print(\"The best algorithm is: Adaptive Boosting Classifier\")\n",
    "else:\n",
    "    print(\"The best algorithm is: Grey Wolf Optimizer Classifier\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "# Create a function to extract the required metrics\n",
    "def extract_metrics(y_true, y_pred):\n",
    "    from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score\n",
    "\n",
    "    precision = precision_score(y_true, y_pred, average='micro')\n",
    "    recall = recall_score(y_true, y_pred, average='micro')\n",
    "    f1 = f1_score(y_true, y_pred, average='micro')\n",
    "    accuracy = accuracy_score(y_true, y_pred)\n",
    "\n",
    "    return {'Precision': precision, 'Recall': recall, 'F1 Score': f1, 'Accuracy': accuracy}\n",
    "\n",
    "# Extract the metrics for both classifiers\n",
    "ab_metrics = extract_metrics(y_test, ab_y_pred)\n",
    "gwo_metrics = extract_metrics(y_test, gwo_y_pred)\n",
    "\n",
    "# Create a DataFrame to display the results\n",
    "results_df = pd.DataFrame({'Adaptive Boosting': ab_metrics, 'Grey Wolf Optimizer': gwo_metrics})\n",
    "\n",
    "# Display the results in tabular format\n",
    "results_df"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
